import React, { PropsWithChildren } from "react";
import { BrowserRouter, Route, Routes, Navigate, Link, useNavigate, NavigateFunction, Outlet } from 'react-router-dom';
import { Exception, ErrorBoundary, Authorized, AppIcon, filterPermission, trimPath, withBusinessComponent } from "./components";
import type { ProAppIconProps } from './components/pro-appIcon';
import type { RouteConfig } from "./types";

export interface ProRouterProps {
  rootPath?: string;
  redirectPath?: string;
  mounted?: (navigate: NavigateFunction) => void;
  appRoutes?: RouteConfig[];
  authorized?: {
    checkLogin?: () => Promise<boolean>,
    noLoginRedirectPath?: string,
    noVerifyLoginPathList?: string[],
    permissions?: string[];
  },
  appIconComponent?: React.FC<ProAppIconProps>
  ThemeConfigProvider?: React.FC<PropsWithChildren>
}

export const ProRouter: React.FC<ProRouterProps> = ({ rootPath, redirectPath, mounted, authorized = {}, appRoutes, appIconComponent: RealAppIcon, ThemeConfigProvider }) => {
  const { checkLogin, noLoginRedirectPath, noVerifyLoginPathList, permissions } = authorized;
  const realNoVerifyLoginPathList = (noVerifyLoginPathList ?? []).map(path => trimPath(path));

  // 解析路由
  const parseRoute = (appRoutes: RouteConfig[]) => {
    return appRoutes.map(item => {
      if (!item) return null;
      let { path, redirect, children, icon, props = {} } = item;
      const BusinessComponent = withBusinessComponent(item, ThemeConfigProvider);

      // TODO 如果没有固定设置redirect，将获取第一个route来跳转
      if (!redirect && children && children.length > 0 && children[0]) {
        redirect = children[0].path
      }

      if (icon && !React.isValidElement(icon)) {
        item.icon = RealAppIcon ? <RealAppIcon {...icon} /> : <AppIcon {...icon} />
      }

      const RouteWrapper: React.FC = () => {
        return <ErrorBoundary>
          <Authorized currentPath={path} checkLogin={checkLogin} noLoginRedirectPath={noLoginRedirectPath} noVerifyLoginPathList={realNoVerifyLoginPathList}>
            <BusinessComponent route={item} {...props}>
              <Outlet />
            </BusinessComponent>
          </Authorized>
        </ErrorBoundary>
      }

      return (
        <Route key={path} path={path} element={<RouteWrapper />}>
          {parseRoute(children || [])}

          {/*重定向*/}
          {redirect && <Route path={path} element={<Navigate to={redirect} />} />}

          {/*404页面*/}
          <Route path="*" element={<Exception type="404" style={{ minHeight: 500, height: '100%' }} linkElement={Link} />} />
        </Route>
      )
    })
  }

  const routeList = parseRoute(filterPermission(appRoutes, permissions));

  return (
    <ErrorBoundary>
      <BrowserRouter>
        <RouterMount mounted={mounted} />
        <Routes>
          <Route path={rootPath} element={<Navigate to={redirectPath} />} />
          <Route path="/" element={<Navigate to={redirectPath} />} />

          {routeList}
          {/*404页面*/}
          <Route path="*" element={<Exception type="404" style={{ minHeight: 500, height: '100%' }} linkElement={Link} />} />
        </Routes>
      </BrowserRouter>
    </ErrorBoundary>
  )
}


const RouterMount: React.FC<{ mounted: (navigate: NavigateFunction) => void; }> = ({ mounted }) => {
  mounted && mounted(useNavigate())
  return null;
}



